#include "..\\code\\dataStruct.h"
#include "..\\code\\common.h"


extern void buscoupleOverCurrentRelay(Device *device);

extern void buscoupleZeroCurrentRelay(Device *device);

extern void buscoupleTrip(Device *device);

void buscouple(Device *device) {

    // 误码生成替换
    errorDataOperation(device);

    // 如果当前相量数据错误
    if (isDataValid(device, 0) == 0) return;

    // 将采样值存入瞬时值数组
    sample2inst(device);

    // 瞬时值滤波后存入并更新滤波后数组
    dataFilter(device);

    // 利用滤波后数据计算12通道相量, 存入phasor数组
    toPhasor(device);

    if (device->time < STABLE_TIME) {
        // 等待仿真进入稳定状态
        return;
    }


    // 1.相过流保护
    buscoupleOverCurrentRelay(device);

    // 2.零序过流
    buscoupleZeroCurrentRelay(device);

    // 3.动作出口
    buscoupleTrip(device);
}


void buscoupleOverCurrentRelay(Device *device) {
    if (device->buscouple.overCurrentEnable == 0) return;
    if (device->buscouple.overCurrentTripFlag == 1) return;

    int phase = 0;

    // I段启动判定
    if (device->buscouple.overCurrentOneStartFlag == 0) {
        double IcA = phasorAbs(device->phasor[3]);
        double IcB = phasorAbs(device->phasor[4]);
        double IcC = phasorAbs(device->phasor[5]);

        double IcMax = max3(IcA, IcB, IcC);


        if (IcMax > 0.95 * device->buscouple.overCurrentOneSetValue) {
            writePlainLog(device, "母联过电流I段保护启动");
            device->buscouple.overCurrentOneStartFlag = 1;
            device->buscouple.overCurrentOneStartTime = device->time;
        }
    }
    // I段动作判定
    if (device->buscouple.overCurrentOneStartFlag == 1) {
        double IcA = phasorAbs(device->phasor[3]);
        double IcB = phasorAbs(device->phasor[4]);
        double IcC = phasorAbs(device->phasor[5]);

        double IcMax = max3(IcA, IcB, IcC);

        if (device->time > device->buscouple.overCurrentOneStartTime + device->buscouple.overCurrentOneTimeSetValue &&
            IcMax > 0.95 * device->buscouple.overCurrentOneSetValue) {
            device->buscouple.overCurrentTripFlag = 1;
            writePlainLog(device, "母联过电流I段保护动作");
        }
    }

    // II段启动判定
    if (device->buscouple.overCurrentTwoStartFlag == 0) {
        double IcA = phasorAbs(device->phasor[3]);
        double IcB = phasorAbs(device->phasor[4]);
        double IcC = phasorAbs(device->phasor[5]);

        double IcMax = max3(IcA, IcB, IcC);

        if (IcMax > 0.95 * device->buscouple.overCurrentTwoSetValue) {
            writePlainLog(device, "母联过电流II段保护启动");
            device->buscouple.overCurrentTwoStartFlag = 1;
            device->buscouple.overCurrentTwoStartTime = device->time;
        }
    }
    // II段动作判定
    if (device->buscouple.overCurrentTwoStartFlag == 1) {
        double IcA = phasorAbs(device->phasor[3]);
        double IcB = phasorAbs(device->phasor[4]);
        double IcC = phasorAbs(device->phasor[5]);

        double IcMax = max3(IcA, IcB, IcC);

        if (device->time > device->buscouple.overCurrentTwoStartTime + device->buscouple.overCurrentTwoTimeSetValue &&
            IcMax > 0.95 * device->buscouple.overCurrentTwoSetValue) {
            device->buscouple.overCurrentTripFlag = 1;
            writePlainLog(device, "母联过电流II段保护动作");
        }
    }


}


void buscoupleZeroCurrentRelay(Device *device) {
    if (device->buscouple.zeroCurrentEnable == 0) return;
    // 保护动作后不再判定, 锁存动作结果
    if (device->buscouple.zeroCurrentTripFlag == 1) return;

    int phase = 0;
    // 仅在没有启动的情况下才进行启动判据判别, 避免启动时间被覆盖
    if (device->buscouple.zeroCurrentStartFlag == 0) {
        Phasor IpA = device->phasor[3];
        Phasor IpB = device->phasor[4];
        Phasor IpC = device->phasor[5];

        Phasor zeroPhase = phasorAdd(phasorAdd(IpA, IpB), IpC);
        double zeroAbs = phasorAbs(zeroPhase);

        if (zeroAbs > 0.95 * device->buscouple.zeroCurrentSetValue) {
            writePlainLog(device, "母联零序过电流保护启动");
            device->buscouple.zeroCurrentStartFlag = 1;
            device->buscouple.zeroCurrentStartTime = device->time;
        }
    }

    // 如果零序保护已经启动才进入判别
    if (device->buscouple.zeroCurrentStartFlag == 1) {
        Phasor IpA = device->phasor[3];
        Phasor IpB = device->phasor[4];
        Phasor IpC = device->phasor[5];

        Phasor zeroPhase = phasorAdd(phasorAdd(IpA, IpB), IpC);
        double zeroAbs = phasorAbs(zeroPhase);
        // 三条件, 时间+条件+(启动)
        if (device->time > device->buscouple.zeroCurrentStartTime + device->buscouple.zeroCurrentTimeSetValue &&
            zeroAbs > 0.95 * device->buscouple.zeroCurrentSetValue) {
            device->buscouple.zeroCurrentTripFlag = 1;
            writePlainLog(device, "母联零序过电流保护动作");
        }
    }
}

void buscoupleTrip(Device *device) {
    if (device->buscouple.overCurrentTripFlag == 1 ||
        device->buscouple.zeroCurrentTripFlag == 1) {
        int i = 0;
        for (; i < 3; i++) {
            device->outRes[i] = 1;
        }
        writeLog(device, "母联保护动作出口");
    }

}


